﻿#include<iostream>
#include<cstring>

// 实验一些c++初始化相关的语法
// 
// 列表初始化（Uniform Initialization）
// C++11 引入了列表初始化，使用花括号 {} 来初始化变量。它可以用于初始化数组、结构体、类对象等，并且在初始化自定义类型时，会优先调用 std::initializer_list 构造函数（如果存在）。
// 
// 值初始化（Value Initialization）：
// 值初始化是一种特殊的初始化方式，对于内置类型，它会将变量初始化为 0（对于指针类型初始化为 nullptr）；对于自定义类型，会调用默认构造函数，如果没有默认构造函数，则会使用"默认成员初始化器"进行初始化。
// 
// 默认成员初始化器
//

// 【4】ch2.2.1
//The value of an object of built-in type that is not explicitly initialized depends on where it is defined.
//Variables defined outside any function body are initialized to zero. 
//未初始化的“全局变量和全局静态变量、局部静态变量，他们在执行模块文件中，存放于.bss节（挂名，不占内存），执行加载到内存时，会放置在初始化未0的一片内存中
//
int ivvv_global;
char chvvv_global;
float fvvv_global;
double dvvv_global;

void TestBuiltInTypeGlobalVariblesInitializedOutPut() {
    std::cout
        << "\t ivvv_global:" << ivvv_global
        << "\t chvvv_global:" << (int)chvvv_global
        << "\t fvvv_global:" << fvvv_global
        << "\t dvvv_global:" << dvvv_global
        << std::endl;//确实输出的结果都是0， vs2022，debug模式
}

class TestData {
public:
    const static int InitIVValue = 999;
    const static int MemoryTestSize = 10;
    int iv_{ InitIVValue };
    char* memory_manage_{ nullptr };
    ~TestData() {
        std::cout << "run in TestData destructor" << std::endl;
        delete[] memory_manage_; //无需判断是否为nullptr
    }
    //TestData(const TestData& obj) :iv_(obj.iv_) {
    //    std::clog << "run in TestData copy constructor" << std::endl;
    //    //memory_manage_ = nullptr;//有上面定义时候的列表初始化，这句不必要
    //    if (obj.memory_manage_)
    //    {
    //        memory_manage_ = new char[MemoryTestSize];
    //        memcpy(memory_manage_, obj.memory_manage_, MemoryTestSize);
    //    }
    //}
    TestData& operator=(const TestData& obj) {
        std::cout << "run in TestData operator= fun" << std::endl;
        if (this == &obj) {
            return *this;
        }
        iv_ = obj.iv_;
        if (memory_manage_)
        {
            delete[] memory_manage_;
            memory_manage_ = nullptr;
        }
        if (obj.memory_manage_)
        {
            memory_manage_ = new char[MemoryTestSize];
            memcpy(memory_manage_, obj.memory_manage_, MemoryTestSize);
        }
        return *this;
    }
    //TestData() = default;//即使是保留了这一句，TestListMemberInitializers函数编译也会报错“error C2440: “初始化”: 无法从“initializer list”转换为“TestData””
    //virtual void funv(){} //有这一句也报错
};



//use "a braced list of member initializers",需要（下面四点摘自参考【4】ch7.5.5：
// •All of its data members are public
// •It does not define any constructors
// •It has no in-class initializers //经测试 TestData 类中有类内初始值也能食用 成员初始值列表 来初始构建对象：
// •It has no base classes or virtual functions
//
void TestListMemberInitializers() {
    TestData obj{ 3, nullptr };
    std::cout << obj.iv_ << std::endl; //3

    TestData objdef{  };
    std::cout << objdef.iv_ << std::endl;// 999
}

//#include<initializer_list>
// Unlike vector, the elements in an initializer_list are always const values; there is no way to change the value of an element in an initializer_list.
// An object of type std::initializer_list<T> is a lightweight proxy object that provides access to an array of objects of type const T(that may be allocated in read - only memory).
// initializer_list 中的对象永远是常量值
void TestInitializerList() {
    std::initializer_list<int> listObj;
    auto isize = listObj.size();//智能提示只能点出来四个函数
    std::cout << "Empty list size: " << isize << std::endl;
    
    std::initializer_list<int> listObjValue{ 1,44,224 };
    isize = listObjValue.size();
    std::cout << "List with values size: " << isize << std::endl;
    
    auto iv = listObjValue.begin();// const int *
    std::cout << "First element: " << *iv << std::endl;
}
#include "test_fwd.h"
int run_main_initialization()
{
    fun_test_fwd("");
    TestListMemberInitializers();
    TestInitializerList();
    TestBuiltInTypeGlobalVariblesInitializedOutPut();
    return 0;
}

int main()
{
    return run_main_initialization();
}
